﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Common
{
    //文件名不能包含以下字符：冒号 ：分隔符 | 正反斜杠 \ / 星号* 左右尖括号< > 问号 ？英语里的双引号 "
    //【\  】【 / 】  ：这两个符号代表路径，如果文件夹（目录）中也包含这些的话，地址会混淆不清，无法区分
    //【:  】：英文的冒号是访问协议和传输的符号，会跟网址等混淆。
    //【*】【？】：这是通配符，在搜索文件的时候使用，所以不能使用。
    //【<】【> 】【| 】【"】 ：这些符号在编程的时候经常用到函数中作为运算符等，避免程序出错，故而这些符号也不能作为文件或文件夹的名称。
    //一级分隔符：|   二级分隔符：<   三级分隔符：>
    public class ClassTransportInfo
    {
        public Guid TransGuid { set; get; }
        public string RootPath { set; get; }
        public List<ClassFileInfo> Files { set; get; }

        public ClassTransportInfo()
        {
            Files = new List<ClassFileInfo>(10);
        }

        public ClassTransportInfo(string[] paths)
        {
            List<string> list = PathHelper.GetDirectory2List(paths);

            TransGuid = Guid.NewGuid();
            RootPath = list[0];
            Files = new List<ClassFileInfo>(list.Count - 1);
            for (int i = 1; i < list.Count; i++)
            {
                FileInfo info = new FileInfo(list[0] + list[i]);
                ClassFileInfo file = new ClassFileInfo();
                file.RelativePath = list[i];
                file.FileSize = info.Length;
                Files.Add(file);
            }
        }
        
        public string Coding2String()
        {
            string b = null;
            b += TransGuid.ToString() + '|';
            b += RootPath + '|';
            foreach(ClassFileInfo file in Files)
            {
                b += file.Coding2String() + '<';
            }
            return b;
        }

        public void DecodingFromString(string message)
        {
            string[] buffer = message.Split('|');
            TransGuid = new Guid(buffer[0]);
            RootPath = buffer[1];
            string[] buffe = buffer[2].Split('<');
            foreach(string buff in buffe)
            {
                if(buff.Equals("") | buff == null)
                {
                    break;
                }
                ClassFileInfo file = new ClassFileInfo();
                file.DecodingFromString(buff);
                Files.Add(file);
            }
        }

        public override bool Equals(object obj)
        {
            var other = obj as ClassTransportInfo;
            if(other != null)
            {
                if(Files.TrueForAll(other.Files.Contains) && Files.Count == other.Files.Count & RootPath == other.RootPath)
                {
                    return true;
                }
            }
            return false;
        }

        public static bool operator ==(ClassTransportInfo infoL, ClassTransportInfo infoR)
        {
            if (ReferenceEquals(infoL, infoR)) return true;
            if ((object)infoL == null | (object)infoR == null)
            {
                return false;
            }
            return infoL.Equals(infoR);
        }
        public static bool operator !=(ClassTransportInfo infoL, ClassTransportInfo infoR) => !(infoL == infoR);

        public override int GetHashCode()
        {
            return Coding2String().GetHashCode();
        }
    }

    /// <summary>
    /// 单个文件类
    /// </summary>
    public class ClassFileInfo
    {
        /// <summary>
        /// 相对路径
        /// </summary>
        public string RelativePath
        {
            set;
            get;
        }
        /// <summary>
        /// 文件大小
        /// </summary>
        public long FileSize
        {
            set;
            get;
        }

        public string Coding2String()
        {
            string b = null;
            b += RelativePath + ">";
            b += FileSize;
            return b;
        }

        public void DecodingFromString(string message)
        {
            string[] buff = message.Split('>');
            RelativePath = buff[0];
            FileSize = long.Parse(buff[1]);
        }

        public override bool Equals(object obj)
        {
            var other = obj as ClassFileInfo;
            if(obj != null)
            {
                return RelativePath == other.RelativePath && FileSize == other.FileSize;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return Coding2String().GetHashCode();
        }
    }
}
